import qs from 'query-string';
import moment from 'moment';
import { Netmask } from 'netmask';
import * as XLSX from 'xlsx';
import randomString from 'random-string';

// 毫秒转换日时分秒(时间长度 )
const formatTime = (time) => {
    const days = parseInt(time / (1000 * 60 * 60 * 24));
    const hours = parseInt((time % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    const minutes = parseInt((time % (1000 * 60 * 60)) / (1000 * 60));
    const seconds = Math.round((time % (1000 * 60)) / 1000);
    if (time < 500) {
        return `${0} 秒 `;
    } else if (time >= 500) {
        if (days === 0) {
            if (hours === 0) {
                if (minutes === 0) {
                    return `${seconds} 秒 `;
                }
                return `${minutes} 分钟 ${seconds} 秒 `;
            }
            return `${hours} 小时 ${minutes} 分钟 ${seconds} 秒 `;
        }
        return `${days} 天 ${hours} 小时 ${minutes} 分钟 ${seconds} 秒 `;
    }
};

// 时间戳转换年月日(时间点)
const timestampToTime = (timestamp, type, extra, noShowDay) => {
    if (typeof timestamp === 'undefined') return '-';
    if (!timestamp) return '-';
    // 10位需*1000
    const date = new Date(parseInt(timestamp));
    const Y = `${date.getFullYear()}-`;
    const M = `${date.getMonth() + 1 < 10 ? `0${date.getMonth() + 1}` : date.getMonth() + 1}-`;
    const D = `${date.getDate() < 10 ? `0${date.getDate()}` : date.getDate()} `;
    const h = `${date.getHours() < 10 ? `0${date.getHours()}` : date.getHours()}`;
    const m = `${date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes()}`;
    const s = date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds();
    let strDate = '';
    if (type == 'day') {
        strDate = Y + M + D;
        // console.log(strDate); //2020-06-11
    } else if (type == 'hour') {
        strDate = Y + M + D + h + (extra || '');
        // console.log(strDate); //2020-06-11 05
    } else if (type == 'minute') {
        strDate = noShowDay ? h + ':' + m : Y + M + D + h + ':' + m;
        // console.log(strDate); //2020-06-11 05:08
    } else {
        strDate = Y + M + D + h + ':' + m + ':' + s;
        // console.log(strDate); //2020-06-11 19:28:56
    }
    return strDate;
};

// 对象undefined属性清除
const clearDeep = (obj) => {
    if (!obj || !typeof obj == 'object') return;
    const keys = Object.keys(obj);
    for (const key of keys) {
        const val = obj[key];
        if (typeof val === 'undefined' || ((typeof val === 'object' || typeof val === 'string') && !val)) {
            delete obj[key];
        } else if (typeof val === 'object') {
            clearDeep(obj[key]);
            if (Object.keys(obj[key]).length === 0) {
                delete obj[key];
            }
        }
    }
};

const bytesToSize = (bytes, fixedNum = 3) => {
    if (bytes === '0' || bytes === 0 || !bytes) return '0 Byte';
    const k = 1024;
    const sizes = ['Byte', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
    let i = Math.floor(Math.log(bytes) / Math.log(k));
    if (i < 1) i = 0;
    const value = bytes / Math.pow(k, i);
    return `${value.toFixed(fixedNum)} ${sizes[i]}`;
};

const bytesToSizeWithUnit = (bytes, unit = 'Byte', fixedNum = 3) => {
    if (bytes === 0 || !bytes) return `0`;
    const sizes = ['Byte', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
    const u = unit.split('/')[0];
    const i = sizes.indexOf(u);
    if (i == -1) return bytes;
    const k = 1024;
    const value = bytes / Math.pow(k, i);
    return value.toFixed(fixedNum);
};

const getUser = () => {
    let user = {};
    const str = localStorage.getItem('_wocloud_storage_');

    if (str) {
        const obj = JSON.parse(str);
        if (obj.__login_info__ && obj.__login_info__.value) {
            user = obj.__login_info__.value;
        }
    }
    return user;
};

const getToken = () => {
    let str = localStorage.getItem('_wocloud_storage_');

    if (str) {
        let obj = JSON.parse(str);
        if (obj.token) {
            return obj.token.value;
        }
    }
    return null;
};

const sendPostMessage = (url, params = {}, receiveMessage) => {
    // 向该窗口发送消息
    let urlParse = {};
    try {
        urlParse = new URL(url); // 解析
    } catch (e) {
        prompt.error('无法解析URL地址，操作失败！');
        return false;
    }
    const domainUrl = urlParse.origin; // 域名

    const popupwin = window.open(url);
    let postTime = 0;
    const timer = setInterval(() => {
        popupwin.postMessage(params, url);
        postTime += 500;
        // 30s超时后自动关闭
        if (postTime == 30000) {
            prompt.error('操作失败，页面加载超时！');
            clearInterval(timer);
        }
    }, 500);

    let msgFn = (e) => {
        if (e.origin.includes(domainUrl)) {
            if (e.data.status === 200) {
                console.log(domainUrl + ' 接收到token');
                if (receiveMessage instanceof Function && timer) receiveMessage(e);
                // 当收到反馈时就不在发送
                clearInterval(timer);
                window.removeEventListener('message', msgFn, false);
            }
        }
    };
    window.addEventListener('message', msgFn, false);
};

const debounce = (fn, wait) => {
    let timeout = null;
    return function () {
        const context = this;
        const args = arguments;
        if (timeout) clearTimeout(timeout);
        timeout = setTimeout(() => {
            fn.apply(context, args);
        }, wait);
    };
};

const hcpcloudbrand = ['wocloud', 'aliyun-', 'huawei-'];

const isOperableBrand = (brand) => {
    return ['woclou', 'aliyun', 'huawei'].indexOf(brand) !== -1;
};

// 操作限制，是否允许进行操作
const allowOperation = (data) => {
    // return (
    //   ["woclou", "aliyun", "huawei"].indexOf(data.cloudBrand?.substr(0, 6)) !==
    //     -1 &&
    //   data.accountId &&
    //   data.cloudRegionId
    // );
    return true;
};

const stringify = (obj) => {
    const query = {};
    Object.keys(obj)
        .filter((key) => obj[key] !== undefined && obj[key] !== null && obj[key] !== '')
        .forEach((key) => {
            query[key] = obj[key];
        });
    return qs.stringify(query);
};

// 监听事件方法
const addEvent = (element, event, handler) => {
    if (element.addEventListener) {
        element.addEventListener(event, handler);
    } else if (element.attachEvent) {
        element.attachEvent(`on${event}`, handler);
    } else {
        element[`on${event}`] = handler;
    }
};

// 移除事件方法
const removeEvent = (element, event, handler) => {
    if (element.removeEventListener) {
        element.removeEventListener(event, handler, false);
    } else if (element.detachEvent) {
        element.detachEvent(`on${event}`, handler);
    } else {
        element[`on${event}`] = null;
    }
};

// format tree data
const loopTree = (data) =>
    data.map((item) => {
        item.title = `${item.orgDisplayName || '-'}`;
        item.key = item.orgCode;
        if (item.children) {
            return { title: item.title, key: item.key, children: loopTree(item.children) };
        }
        return {
            title: item.title,
            key: item.key,
        };
    });

// tree数据结构添加key
const treeDataKeys = (data, keyIndex) => {
    data.map((item) => {
        item.key = item[keyIndex];
        if (item.children) treeDataKeys(item.children, keyIndex);
    });
};
// tree数据迭代修改
const treeDataIteration = (data, fun) => {
    data.map((item) => {
        fun(item);
        if (item.children) treeDataIteration(item.children, fun);
    });
};

const parseData = (value) => {
    const copy = JSON.parse(JSON.stringify(value));
    Object.keys(copy).forEach((key) => {
        try {
            let obj = JSON.parse(copy[key]);
            if (typeof obj == 'object') {
                //防止精度丢失
                copy[key] = obj;
            }
        } catch (e) {}
    });
    return copy;
};

const isJSON = (str) => {
    if (typeof str === 'string') {
        try {
            const obj = JSON.parse(str);
            if (typeof obj === 'object' && obj) {
                return true;
            } else {
                return false;
            }
        } catch (e) {
            return false;
        }
    } else if (typeof str === 'object' && str) {
        return true;
    }
};

// 获取根路径
const getFrontHref = () => {
    const hrefArr = window.location.href.split('/');
    const index = hrefArr.findIndex((i) => {
        return i === 'res';
    });
    const frontHref = hrefArr.slice(0, index).join('/');
    return frontHref;
};

//将十进制数字转换成8位二进制
function fomartIP(ip) {
    let dec = ip;
    let bin = '';
    while (dec > 0) {
        if (dec % 2 != 0) {
            bin = '1' + bin;
        } else {
            bin = '0' + bin;
        }
        dec = parseInt(dec / 2);
    }
    var length = bin.length;
    if (length < 8) {
        var nul = 8 - length;
        var count = 0;
        var str = '';
        while (count < nul) {
            str += '0';
            count++;
        }
        bin = str + bin;
    }
    return bin;
}

/** ---  私网cidr计算 --  */

// 最终结果
function cidrToRangeByArr(cidr, parentCidr) {
    if (!cidr) return;

    // 获取地址范围块
    function urlRangeFun(urlRange) {
        if (typeof urlRange == 'undefined') return {};
        let array = urlRange.split('/');
        let mask = Number(array[1]);
        let startArr = array[0].split('.'),
            endArr = [];
        let segment1 = Number(startArr[0]);
        let segment2 = Number(startArr[1]);
        let segment3 = Number(startArr[2]);
        let segment4 = Number(startArr[3]);
        let startBin = fomartIP(segment1) + fomartIP(segment2) + fomartIP(segment3) + fomartIP(segment4);
        let endBin = '';
        // 获取要截取的下标
        let indexArr = [];
        for (let i = -1; (i = startBin.indexOf('1', i + 1)) > -1; indexArr.push(i));
        let startIndex = indexArr[indexArr.length - 1];
        let endIndex = mask - 1;
        let middleIndex = endIndex - startIndex;
        let str = '';
        for (let i = 0; i < middleIndex; i++) {
            str += '1';
        }
        // 截取计算出变化的末尾值
        endBin = startBin.slice(0, startIndex + 1) + str + startBin.slice(endIndex + 1);
        for (let index = 0; index < endBin.length; index += 8) {
            endArr.push(parseInt(endBin.slice(index, index + 8), 2));
        }
        return {
            mask, // 掩码
            startArr, // 开始地址数组
            endArr, // 结束地址数组
        };
    }

    // 根据mask计算变更位
    function positionFun(mask) {
        if (typeof mask == 'undefined') return {};
        let bytePosition = Math.ceil(mask / 8) - 1;
        let bitPosition = parseInt(mask % 8) === 0 ? 0 : 8 - parseInt(mask % 8);
        return {
            bytePosition, // 字节位
            bitPosition, // 变更位
        };
    }

    // 当前的cidr计算结果值
    let { mask, startArr, endArr } = urlRangeFun(cidr);
    let { bytePosition, bitPosition } = positionFun(mask);

    // 父级的cidr计算结果值
    let { mask: parentMask, startArr: parentStartArr } = urlRangeFun(parentCidr);
    let { bytePosition: parentBytePosition, bitPosition: parentBitPosition } = positionFun(parentMask);

    // 计算最终结果
    let res = [];
    for (let i = 0; i < 4; i++) {
        let range = [],
            start = Number(startArr[i]),
            end = Number(endArr[i]);
        if (i == 1 && startArr[i] == 168) {
            // 168判断 c类
            res.push({
                value: startArr[i],
                disabled: true,
            });
            continue;
        }
        if (i == 0 || i > bytePosition) {
            // 判断初始和末尾位置
            res.push({
                value: start,
                disabled: true,
            });
        } else {
            // 父级存在的情况
            if (typeof parentBytePosition !== 'undefined' && parentBytePosition == i) {
                end = Number(parentStartArr[i]) + Math.pow(2, parentBitPosition) - 1;
            }
            if (i == bytePosition) {
                // 判断变更位置
                while (start <= end) {
                    range.push(start);
                    start += Math.pow(2, bitPosition);
                }
                res.push({
                    value: startArr[i],
                    disabled: false,
                    range: range,
                });
            } else {
                // 判断初始到变更位中间部分
                while (start <= end) {
                    range.push(start);
                    start += 1;
                }
                res.push({
                    value: startArr[i], // 当前值
                    disabled: false, // 是否可操作
                    range: range, // 可输入范围
                });
            }
        }
    }
    return res;
}

// route判断方法
function routeToRangeByArr(mask) {
    // 根据mask计算变更位
    let bytePosition = Math.ceil(mask / 8) - 1; // 字节位
    let bitPosition = parseInt(mask % 8) === 0 ? 0 : 8 - parseInt(mask % 8); // 变更位
    // 计算最终结果
    let res = [];
    for (let i = 0; i < 4; i++) {
        let range = [],
            start = 0;
        if (i > bytePosition) {
            // 判断初始和末尾位置
            res.push({
                disabled: true,
            });
        } else if (i == bytePosition) {
            // 判断变更位置
            while (start <= 255) {
                range.push(start);
                start += Math.pow(2, bitPosition);
            }
            res.push({
                disabled: false,
                range: range,
            });
        } else {
            while (start <= 255) {
                range.push(start);
                start += 1;
            }
            res.push({
                disabled: false,
                range: range,
            });
        }
    }
    return res;
}

const convertCidr = (cidr) => {
    let { first, last } = new Netmask(cidr);
    let firstArr = first.split('.');
    let lastArr = last.split('.');
    let firstBin =
        fomartIP(Number(firstArr[0])) +
        fomartIP(Number(firstArr[1])) +
        fomartIP(Number(firstArr[2])) +
        fomartIP(Number(firstArr[3]));
    let lastBin =
        fomartIP(Number(lastArr[0])) +
        fomartIP(Number(lastArr[1])) +
        fomartIP(Number(lastArr[2])) +
        fomartIP(Number(lastArr[3]));
    return [parseInt(firstBin, 2), parseInt(lastBin, 2)];
};

const diffCidr = (arr1, arr2) => {
    let min1 = Math.min(...arr1),
        max1 = Math.max(...arr1);
    let min2 = Math.min(...arr2),
        max2 = Math.max(...arr2);
    let diffMin = Math.max(min1, min2);
    return diffMin == min1 ? diffMin > max2 : diffMin > max1; // 返回true无交集,false存在交集
};

// 多个cidr重复校验
const checkCidrsIsRepeat = (arr) => {
    // arr = [{name:"子网名称",cidr:"192.169.0.0/17"}]
    if (!(arr && Array.isArray(arr) && arr.length > 0)) return;
    for (let i = 0; i < arr.length - 1; i++) {
        let cidr1 = arr[i].cidr,
            name1 = arr[i].name;
        let diff1 = convertCidr(cidr1);
        for (let j = i + 1; j < arr.length; j++) {
            let cidr2 = arr[j].cidr,
                name2 = arr[j].name;
            let diff2 = convertCidr(cidr2);
            let diffRes = diffCidr(diff1, diff2);
            if (!diffRes) return [name1, name2];
        }
    }
    return false;
};

const flattenArray = (arr) => {
    while (arr.some((item) => Array.isArray(item))) {
        arr = [].concat(...arr);
    }
    return arr;
};

// 得到前7天的天数数组
function getBefore7DaysArray(format) {
    return [
        moment().subtract('days', 6).format(format),
        moment().subtract('days', 5).format(format),
        moment().subtract('days', 4).format(format),
        moment().subtract('days', 3).format(format),
        moment().subtract('days', 2).format(format),
        moment().subtract('days', 1).format(format),
        moment().format(format),
    ];
}

function deepCompare(x, y) {
    var i, l, leftChain, rightChain;
    function compare2Objects(x, y) {
        var p;
        // remember that NaN === NaN returns false
        // and isNaN(undefined) returns true
        if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {
            return true;
        }
        // Compare primitives and functions.
        // Check if both arguments link to the same object.
        // Especially useful on the step where we compare prototypes
        if (x === y) {
            return true;
        }
        // Works in case when functions are created in constructor.
        // Comparing dates is a common scenario. Another built-ins?
        // We can even handle functions passed across iframes
        if (
            (typeof x === 'function' && typeof y === 'function') ||
            (x instanceof Date && y instanceof Date) ||
            (x instanceof RegExp && y instanceof RegExp) ||
            (x instanceof String && y instanceof String) ||
            (x instanceof Number && y instanceof Number)
        ) {
            return x.toString() === y.toString();
        }
        // At last checking prototypes as good as we can
        if (!(x instanceof Object && y instanceof Object)) {
            return false;
        }
        if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {
            return false;
        }
        if (x.constructor !== y.constructor) {
            return false;
        }
        if (x.prototype !== y.prototype) {
            return false;
        }
        // Check for infinitive linking loops
        if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {
            return false;
        }
        // Quick checking of one object being a subset of another.
        // todo: cache the structure of arguments[0] for performance
        for (p in y) {
            if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
                return false;
            } else if (typeof y[p] !== typeof x[p]) {
                return false;
            }
        }
        for (p in x) {
            if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
                return false;
            } else if (typeof y[p] !== typeof x[p]) {
                return false;
            }
            switch (typeof x[p]) {
                case 'object':
                case 'function':
                    leftChain.push(x);
                    rightChain.push(y);

                    if (!compare2Objects(x[p], y[p])) {
                        return false;
                    }

                    leftChain.pop();
                    rightChain.pop();
                    break;

                default:
                    if (x[p] !== y[p]) {
                        return false;
                    }
                    break;
            }
        }
        return true;
    }
    if (arguments.length < 1) {
        return true; //Die silently? Don't know how to handle such case, please help...
        // throw "Need two or more arguments to compare";
    }
    for (i = 1, l = arguments.length; i < l; i++) {
        leftChain = []; //Todo: this can be cached
        rightChain = [];
        if (!compare2Objects(arguments[0], arguments[i])) {
            return false;
        }
    }
    return true;
}
function thousandsFormatNumber(num) {
    let value = 0;
    if (!num && Number(num) !== 0) {
        return '--';
    }
    if (num === '-') {
        return '--';
    }
    if (num === '') {
        return '--';
    }
    if (isNaN(num)) {
        value = Number(num);
        if (isNaN(value)) {
            return '--';
        }
    } else {
        value = num;
    }
    return ('' + value).replace(/(\d{1,3})(?=(\d{3})+(?:$|\.))/g, '$1,');
}
function formatNumber(num) {
    let value = 0;
    if ((!num && Number(num) !== 0) || num === '') {
        return '-';
    }
    if (isNaN(num)) {
        value = Number(num);
        if (isNaN(value)) {
            return '-';
        }
    } else {
        value = num;
    }
    return '' + value;
}
function formatRateValue(value, n) {
    if (!value || value === null || value === '') {
        if (value === 0) {
            return '0%';
        } else {
            return '-';
        }
    } else {
        let valueStr = value + '';
        let index = valueStr.indexOf('.');
        if (index !== -1 && valueStr.length > index + n + 1) {
            if (valueStr[index + n - 1] === '0') {
                if (!(valueStr[index + n] === '0')) {
                    value = parseFloat(value).toFixed(n);
                } else {
                    value = parseInt(value);
                }
            } else {
                if (valueStr[index + n] === '0') {
                    value = parseFloat(value).toFixed(n - 1);
                } else {
                    value = parseFloat(value).toFixed(n);
                }
            }
        }
        return value === '-' ? value : value + '%';
    }
}

// 导出是首行添加筛选条件展示
function exportScreenHandle(headers, screen) {
    // screen传入对象
    let initIndex = 1; // 初始行
    const merges = []; // 合并单元格
    const _screen = {}; // 筛选条件
    if (screen && Object.keys(screen).length > 0) {
        let str = '';
        Object.keys(screen).forEach((key) => {
            let s = ` ${key}：${screen[key]} `;
            str += s;
        });
        _screen[`${String.fromCharCode(65)}1`] = { v: str };
        initIndex = 2;
        merges.push({
            s: {
                c: 0,
                r: 0,
            },
            e: {
                c: Object.keys(headers).length - 1,
                r: 0,
            },
        });
    }
    return { initIndex, merges, _screen };
}

function exportExcel(headers, data, fileName = '统计.xlsx', screen) {
    let { initIndex, merges, _screen } = exportScreenHandle(headers, screen);
    const _headers = headers
        .map((item, i) =>
            Object.assign({}, { key: item.key, title: item.title, position: String.fromCharCode(65 + i) + initIndex })
        )
        .reduce((prev, next) => Object.assign({}, prev, { [next.position]: { key: next.key, v: next.title } }), {});

    const _data = data
        .map((item, i) =>
            headers.map((key, j) =>
                Object.assign(
                    {},
                    { content: item[key.key], position: String.fromCharCode(65 + j) + (i + (initIndex + 1)) }
                )
            )
        )
        // 对刚才的结果进行降维处理（二维数组变成一维数组）
        .reduce((prev, next) => prev.concat(next))
        // 转换成 worksheet 需要的结构
        .reduce((prev, next) => Object.assign({}, prev, { [next.position]: { v: next.content } }), {});

    // 合并 headers 和 data
    const output = Object.assign({}, _screen, _headers, _data);
    // 获取所有单元格的位置
    const outputPos = Object.keys(output);
    // 计算出范围 ,["A1",..., "H2"]
    const ref = `${outputPos[0]}:${outputPos[outputPos.length - 1]}`;

    // 构建 workbook 对象
    const wb = {
        SheetNames: ['Sheet1'],
        Sheets: {
            Sheet1: Object.assign({}, output, {
                '!ref': ref,
                // '!cols': [{ wpx: 100 }, { wpx: 100 }, { wpx: 100 }, { wpx: 100 }, { wpx: 100 }, { wpx: 100 }, { wpx: 100 }, { wpx: 100 }],
                '!merges': merges,
            }),
        },
    };

    // 导出 Excel
    XLSX.writeFile(wb, fileName);
}

// 获取文件流下载文件
function downloadFile(response, fileName) {
    // res为请求返回
    const res = response.data;
    // const fileType = response.headers["content-type"].split(";")[0];
    const url = window.URL.createObjectURL(new Blob([res]));
    const link = document.createElement('a');
    link.style.display = 'none';
    link.href = url;
    link.setAttribute('download', `${fileName}`);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
}

// aws s3 url处理
const awsUrlHandle = (authUrl) => {
    let url = authUrl ? '/obs-wo/' + authUrl.split('/').slice(3).join('/') : '';
    return url;
};

// 文件切片
function createFileChunk(file, chunkSize) {
    const fileChunkList = [];
    let cur = 0;
    while (cur < file.size) {
        fileChunkList.push({ file: file.slice(cur, cur + chunkSize) });
        cur += chunkSize;
    }
    return fileChunkList;
}

// 拼接路径
const spliceFilePath = (path) => {
    let filePath = '';
    if (path) {
        let array = path.split('/');
        for (var i = 0; i < array.length; i++) {
            if (array[i].trim() == '' || array[i] == null || typeof array[i] == 'undefined') {
                array.splice(i, 1);
                i = i - 1;
            }
        }
        filePath = array.join('/');
    }
    return filePath;
};

// 处理响应头，返回Object
const getResponseHeaders = (xhr) => {
    let headers = xhr.getAllResponseHeaders().toLowerCase();
    // 由于返回的是用\r\n来进行分割的字符串，需要做转换
    let arr = headers.trim().split(/[\r\n]+/);
    let headerMap = {};
    arr.forEach(function (line) {
        let parts = line.split(': ');
        let header = parts.shift();
        let value = parts.join(': ');
        headerMap[header] = value;
    });
    return headerMap;
};

// 处理不同标识数据，最终返回处理后的对象 eg:["azIds-432432432432","azIds-432432432432"] 标识为azIds,处理后=> {azIds:[432432432432,432432432432]}
const handleIdentification = (idenData) => {
    let arr = [];
    idenData = idenData || [];
    if (!idenData.length) {
        return {};
    }

    idenData.forEach((item) => {
        let idtf = item.split('-')[0];
        if (arr.indexOf(idtf) == -1) arr.push(`${idtf}`);
    });
    let a = `let ${arr.map((item) => `${item}=[]`)};`;
    let fun = new Function(
        'idenData',
        `
    ${a}
    idenData.forEach(item=>{
      let b = item.split("-");
      ${arr.map((item) => `if(b[0]=='${item}'){${item}.push(b.slice(2).join("-"))};`).join('')}
    });
    return {${arr}};
  `
    );
    return fun(idenData);
};

//判断IP是否在CIDR范围内
const checkIpInCIDR = (gateway, cidr) => {
    let flag = true;
    let obj = cidrToRangeByObject(cidr);
    let array = gateway.split('.');
    let segment1 = array[0];
    let segment2 = array[1];
    let segment3 = array[2];
    //let segment4 = array[3];
    if (
        segment1 <= obj.ip1[1] &&
        segment1 >= obj.ip1[0] &&
        segment2 <= obj.ip2[1] &&
        segment2 >= obj.ip2[0] &&
        segment3 <= obj.ip3[1] &&
        segment3 >= obj.ip3[0]
        //&&(segment4 < obj.ip4[1]&&(segment4 > (obj.ip4[0]+3)))
    ) {
        flag = true;
    } else {
        flag = false;
    }
    return flag;
};
//返回需要的网段范围
const cidrToRangeByObject = (cidr) => {
    if (!cidr) return;
    let obj = {
        ip1: [],
        ip2: [],
        ip3: [],
        ip4: [],
    };
    let array = cidr.split('/');
    let mask = Number(array[1]);
    let ipArray = array[0].split('.');
    let segment1 = ipArray[0];
    let segment2 = Number(ipArray[1]);
    let segment3 = Number(ipArray[2]);
    let segment4 = Number(ipArray[3]);
    let tempBin = fomartIP(segment1) + fomartIP(segment2) + fomartIP(segment3) + fomartIP(segment4);
    let str = '';
    for (let i = 0; i < 32 - mask; i++) {
        str += '1';
    }
    let bin = tempBin.slice(0, mask) + str;
    let binSegment1 = bin.slice(0, 8);
    let binSegment2 = bin.slice(8, 16);
    let binSegment3 = bin.slice(16, 24);
    let binSegment4 = bin.slice(24, 32);
    let _segment1 = Number(ConvertToDecimal(binSegment1));
    let _segment2 = Number(ConvertToDecimal(binSegment2));
    let _segment3 = Number(ConvertToDecimal(binSegment3));
    let _segment4 = Number(ConvertToDecimal(binSegment4));
    obj.ip1.push(segment1);
    obj.ip1.push(_segment1);
    obj.ip2.push(segment2);
    obj.ip2.push(_segment2);
    obj.ip3.push(segment3);
    obj.ip3.push(_segment3);
    obj.ip4.push(segment4);
    obj.ip4.push(_segment4);
    return obj;
};

const ConvertToDecimal = (Bin) => {
    let decimalNumber = 0;
    let numberArray = StringToNumberArray(Bin);
    numberArray.reverse();
    for (let i = 0; i < numberArray.length; i++) {
        decimalNumber += numberArray[i] * Math.pow(2, i);
    }
    return decimalNumber;
};

const StringToNumberArray = (Bin) => {
    let numberArray = [];
    for (let i = 0; i < Bin.length; i++) {
        numberArray.push(Bin.substring(i, i + 1));
    }
    return numberArray;
};

// 实现复制功能, 返回true/false验证复制成功失败
const copyText = (content) => {
    if (!content) return false;
    try {
        const createInput = document.createElement('input');
        createInput.value = content;
        document.body.appendChild(createInput);
        createInput.select(); // 选择对象
        document.execCommand('Copy'); // 执行浏览器复制命令
        createInput.style.display = 'none';
        document.body.removeChild(createInput);
        return true;
    } catch (error) {
        return false;
    }
};

// 判断一个对象是否为promise对象
function isPromise(obj) {
    return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
}

// 得到id,先拿到一个随机id，之后加缓存，得到内存中唯一id
function getId() {
    return randomString({
        length: 14,
        numeric: true,
        letters: true,
        special: false,
    });
}

const filterArray = (arr) => {
    let map = {};
    arr.forEach((v) => {
        map[v.id] = v;
    });
    let treeData = [];

    arr.forEach((child) => {
        const mapItem = map[child.parentId];
        if (mapItem) {
            (mapItem.children || (mapItem.children = [])).push(child);
        } else {
            treeData.push(child);
        }
    });

    return treeData;
};

const timeConversion = (time, formString) => {
    let newTime = Number.isNaN(Number(time)) ? time : Number(time);
    if (!newTime) return '-';
    if (newTime && formString) return moment(newTime).format(formString);
    if (newTime) return moment(newTime);
};

const validateTimestamp = (str) => {
    const timestamp = Number(str);
    if (isNaN(timestamp)) {
        return false;
    }
    const date = new Date(timestamp);
    return date instanceof Date && !isNaN(date);
};

const hcpUtils = {
    formatTime,
    bytesToSize,
    bytesToSizeWithUnit,
    clearDeep,
    getUser,
    getToken,
    sendPostMessage,
    debounce,
    hcpcloudbrand,
    isOperableBrand,
    allowOperation,
    stringify,
    timestampToTime,
    addEvent,
    removeEvent,
    loopTree,
    treeDataKeys,
    treeDataIteration,
    parseData,
    isJSON,
    getFrontHref,
    fomartIP,
    cidrToRangeByArr,
    routeToRangeByArr,
    checkCidrsIsRepeat,
    flattenArray,
    getBefore7DaysArray,
    deepCompare,
    thousandsFormatNumber,
    formatNumber,
    formatRateValue,
    exportExcel,
    downloadFile,
    awsUrlHandle,
    createFileChunk,
    spliceFilePath,
    getResponseHeaders,
    handleIdentification,
    checkIpInCIDR,
    copyText,
    isPromise,
    getId,
    filterArray,
    timeConversion,
    validateTimestamp,
};

export default hcpUtils;
